<template>
  <page>
    <template v-slot:header>
      <h2>
        <span class="icon iconfont">&#xe603;</span>
        <span>{{ $t("system.system_compare") }}</span>
      </h2>
    </template>
    <template v-slot:content>
      <el-card>
        <div slot="header" class="card-header">
          <el-row :gutter="20">
            <el-col :span="16">
              <div>
                <span>{{ $t("system.compare_view") }}</span>
                <el-select
                  v-model="value"
                  class="size"
                  style="vertical-align: middle"
                >
                  <el-option
                    v-for="item in options"
                    :key="item.id"
                    :label="item.name"
                    :value="item.id"
                  >
                  </el-option>
                </el-select>
                <el-radio-group
                  v-model="tag"
                  class="kylin-compare-radio"
                  style="vertical-align: bottom"
                >
                  <el-radio-button label="complete">{{
                    $t("system.complete_comparison")
                  }}</el-radio-button>
                  <el-radio-button :disabled="isBtnDisabled" label="unComplete">{{
                    $t("system.only_changed_lines")
                  }}</el-radio-button>
                </el-radio-group>
              </div>
            </el-col>
            <el-col :span="8" class="compare-button">
              <div>
                <authorization-button
                  class="kylin-item-button"
                  :disabled="!startIp || !endIp"
                  @click="handleDownload"
                  :name="compareName"
                  ref="compare"
                >
                  {{ $t("export") }}
                </authorization-button>
                <authorization-button
                  class="kylin-item-button"
                  :disabled="!startIp || !endIp"
                  @click="loadData"
                  ref="export"
                  :name="exportName"
                >
                  {{ $t("system.compare") }}
                </authorization-button>
              </div>
            </el-col>
          </el-row>
        </div>
        <div>
          <el-row :gutter="20">
            <el-col v-loading="loading" :span="12">
              <div>
                <span class="compare-input-label">IP:</span>
                <div class="compare-div">
                  <el-input
                    class="compare-input-size"
                    v-model="startIp"
                  ></el-input>
                  <div class="ip-error" v-if="startIp_err">
                    {{ $t("ip_error") }}
                  </div>
                  <div class="ip-empty" v-else></div>
                  <div class="compare-view" ref="start">
                    <ul
                      v-if="start.length || startList.length"
                      class="infinite-list"
                      v-infinite-scroll="load"
                      style="overflow: auto"
                      @click="handleClickStart($event)"
                    >
                      <li
                        v-for="(item, index) in startList"
                        :key="index"
                        class="infinite-list-li"
                        :class="getCls(item, index)"
                      >
                        <span class="serial-number">{{ index + 1 }}</span>
                        <template v-if="item.filePath">
                          <span class="infinite-content"
                            >{{ $t("system.configure_file") }}:{{
                              item.filePath
                            }}</span
                          >
                        </template>
                        <template v-else>
                          <span
                            class="infinite-content-key"
                            :title="item.key"
                            >{{ item.key }}</span
                          >
                          <span
                            class="infinite-content-value"
                            :title="item.value"
                            >{{ item.value }}</span
                          >
                        </template>
                      </li>
                    </ul>
                    <div v-else class="no-compare">
                      {{ $t("system.no_compare_item") }}
                    </div>
                  </div>
                </div>
              </div>
            </el-col>
            <el-col v-loading="loading" :span="12">
              <div>
                <span class="compare-input-label">IP:</span>
                <div class="compare-div">
                  <el-input
                    class="compare-input-size"
                    v-model="endIp"
                  ></el-input>
                  <div class="ip-error" v-if="endIp_err">
                    {{ $t("ip_error") }}
                  </div>
                  <div class="ip-empty" v-else></div>
                  <div class="compare-view" ref="end">
                    <ul
                      v-if="end.length || endList.length"
                      class="infinite-list"
                      v-infinite-scroll="load"
                      style="overflow: auto"
                      @click="handleClickEnd($event)"
                    >
                      <li
                        v-for="(item, index) in endList"
                        :key="index"
                        class="infinite-list-li"
                        :class="getCls(item, index)"
                      >
                        <span class="serial-number">{{ index + 1 }}</span>
                        <template v-if="item.filePath">
                          <span class="infinite-content"
                            >{{ $t("system.configure_file") }}:{{
                              item.filePath
                            }}</span
                          >
                        </template>
                        <template v-else>
                          <span
                            class="infinite-content-key"
                            :title="item.key"
                            >{{ item.key }}</span
                          >
                          <span
                            class="infinite-content-value"
                            :title="item.value"
                            >{{ item.value }}</span
                          >
                        </template>
                      </li>
                    </ul>
                    <div v-else class="no-compare">
                      {{ $t("system.no_compare_item") }}
                    </div>
                  </div>
                </div>
              </div>
            </el-col>
          </el-row>
        </div>
      </el-card>
    </template>
  </page>
</template>

<script>
import Page from "@/components/Page";
import {
  systemCompare,
  downloadCompare,
  diffPackage,
  downloadComparePackage,
} from "@/api/system";
import { download } from "@/utils";
import AuthorizationButton from "@/components/AuthorizationButton";
export default {
  name: "system_compare",
  components: {
    Page,
    AuthorizationButton,
  },
  activated() {
      let start = this.$route.query.source;
      let end = this.$route.query.target;
      if (this.startIp && this.endIp) {
          if (this.startIp === start && this.endIp === end) {
              return;
          } else {
              this.startIp = start;
              this.endIp = end;
              this.tag = "complete";
              this.value = "0"
              this.loadData();
          }
      }
  },
  data() {
    return {
      value: "0",
      index: "-1",
      tag: "complete",
      isBtnDisabled: false,
      loading: false,
      count: [],
      packages: [],
      start: [],
      compareName: "HostCompare:compare",
      exportName: "HostCompare:compareDownload",
      end: [],
      startIp: this.$route.query.source || "",
      startIp_err: false,
      endIp: this.$route.query.target || "",
      endIp_err: false,
      startList: [],
      endList: [],
      options: [
        {
          id: "0",
          name: this.$t("configure.dashboard"),
        },
        {
          id: "1",
          name: this.$t("patch.package"),
        },
      ],
    };
  },
  mounted() {
    this.loadData();
  },
  methods: {
    load() {
      if (this.start.length > 0) {
        this.startList.push(this.start.shift());
        this.endList.push(this.end.shift());
      }
    },
    getCls(item, index) {
      const cls = this.index == index ? "diff-click" : "";
      return `${item.cls} ${cls}`;
    },
    parseData(data) {
      if (data) {
        if (data.filePath) {
          this.start.push({ filePath: data.filePath });
          this.end.push({ filePath: data.filePath });
          data.data.forEach((item) => {
            if (item.left == item.right) {
              this.start.push({ key: item.name, value: item.left });
              this.end.push({ key: item.name, value: item.left });
            } else if (item.left == "" || item.right == "") {
              this.start.push({
                key: item.name,
                value: item.left,
                cls: "kylin-compare-add",
              });
              this.end.push({
                key: item.name,
                value: item.right,
                cls: "kylin-compare-add",
              });
            } else {
              this.start.push({
                key: item.name,
                value: item.left,
                cls: "kylin-compare-diff",
              });
              this.end.push({
                key: item.name,
                value: item.right,
                cls: "kylin-compare-diff",
              });
            }
          });
        } else {
          Object.keys(data).map((key) => {
            this.start.push({ filePath: data[key].filePath });
            this.end.push({ filePath: data[key].filePath });
            data[key].data.forEach((item) => {
              if (item.left == item.right) {
                this.start.push({ key: item.name, value: item.left });
                this.end.push({ key: item.name, value: item.left });
              } else {
                this.start.push({
                  key: item.name,
                  value: item.left,
                  cls: "kylin-compare-diff",
                });
                this.end.push({
                  key: item.name,
                  value: item.right,
                  cls: "kylin-compare-diff",
                });
              }
            });
          });
        }
      }
    },
    parsePackage(data) {
      data.forEach((item) => {
        if (item.left == item.right) {
          this.start.push({ key: item.name, value: item.left });
          this.end.push({ key: item.name, value: item.left });
        } else {
          this.start.push({
            key: item.name,
            value: item.left,
            cls: "kylin-compare-diff",
          });
          this.end.push({
            key: item.name,
            value: item.right,
            cls: "kylin-compare-diff",
          });
        }
      });
    },
    loadData() {
      if (!this.startIp || !this.endIp || this.startIp_err || this.endIp_err)
        return;
      this.start = [];
      this.end = [];
      this.startList = [];
      this.endList = [];
      let data = {
        source: this.startIp,
        target: this.endIp,
        isComplete: this.tag == "complete" ? true : false,
      };
      if (this.value === "0") {
      	this.isBtnDisabled = true;
      	this.loading = true;
        systemCompare(data).then((res) => {
        	this.isBtnDisabled = false;
        	this.loading = false;
          if (res.data.code == "0") {
            let { app, kernel, security } = res.data.data;
            this.parseData(app);
            this.parseData(security);
            this.parseData(kernel);
          } else {
            this.$message({
              type: "error",
              message: res.data.message,
            });
          }
        });
      } else {
        diffPackage(data).then((res) => {
          if (res.data.code == "0") {
            this.parsePackage(res.data.data);
          } else {
            this.$message({
              type: "error",
              message: res.data.message,
            });
          }
        });
      }
    },
    handleDownload() {
      if (!this.startIp || !this.endIp || this.startIp_err || this.endIp_err)
        return;
      let data = {
        source: this.startIp,
        target: this.endIp,
        isComplete: this.tag == "complete" ? true : false,
      };
      if (this.value === "0") {
        downloadCompare(data).then((res) => {
          if (res.data.code) {
            this.$message({
              type: "error",
              message: res.data.message,
            });
          } else {
            download(res, "configure-compare");
          }
        });
      } else {
        downloadComparePackage(data).then((res) => {
          if (res.data.code) {
            this.$message({
              type: "error",
              message: res.data.message,
            });
          } else {
            download(res, "package-compare");
          }
        });
      }
    },
    validIp(ip) {
      const str =
        /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/;
      return str.test(ip);
    },
    setIndex(e) {
      let tagName = e.target.nodeName.toLowerCase();
      let index = "";
      if (["li", "span"].includes(tagName)) {
        if (tagName == "li") {
          index = e.target.querySelector(".serial-number").innerHTML.trim();
        } else if (tagName == "span") {
          index = e.target.parentNode
            .querySelector(".serial-number")
            .innerHTML.trim();
        }
        if (this.index == index - 1) {
          this.index = "-1";
        } else {
          this.index = index - 1;
        }
        return true;
      }
      return false;
    },
    handleClickStart(e) {
      const bol = this.setIndex(e);
      if (bol) this.$refs.end.scrollTop = this.$refs.start.scrollTop;
    },
    handleClickEnd(e) {
      const bol = this.setIndex(e);
      if (bol) this.$refs.start.scrollTop = this.$refs.end.scrollTop;
    },
  },
  watch: {
    startIp(value) {
      if (!value) {
        this.startIp_err = false;
      } else {
        if (this.validIp(value)) {
          this.startIp_err = false;
        } else {
          this.startIp_err = true;
        }
      }
    },
    endIp(value) {
      if (!value) {
        this.endIp_err = false;
      } else {
        if (this.validIp(value)) {
          this.endIp_err = false;
        } else {
          this.endIp_err = true;
        }
      }
    },
    tag(newTag) {
      if (this.$refs.compare && this.$refs.compare.display) {
        this.loadData();
      }
    },
    value(newValue) {
      if (newValue === "0") {
        this.compareName = "HostCompare:compare";
        this.exportName = "HostCompare:compareDownload";
      } else {
        this.compareName = "HostCompare:comparePackage";
        this.exportName = "HostCompare:comparePackageDownload";
      }
      if (this.$refs.compare && this.$refs.compare.display) {
        this.loadData();
      }
    },
  },
};
</script>

<style rel="stylesheet/scss" lang="scss" scoped>
.size {
    width: 134px;
}
.compare-button {
  text-align: right;
}
.compare-view {
  height: 350px;
  overflow: auto;
  border: 1px solid #f1f1f1;
}
.compare-input-size {
  width: 100%;
}
.compare-input-label {
  margin-right: 20px;
  display: inline-block;
  vertical-align: top;
  margin-top: 5px;
}
.compare-div {
  width: 90%;
  display: inline-block;
}
.infinite-list {
  padding: 0;
  margin: 0;
  background-color: #fff;
}

.kylin-compare-diff {
  background-color: #ffdddd !important;
  color: #dd1144;
}

.kylin-compare-add {
  background-color: #ccffdd !important;
  color: #c96a4f;
}

.diff-click {
  background-color: #f4f4f4 !important;
}

.infinite-list-li {
  list-style-type: none;
  background-color: #f1f8ff;
  margin-bottom: 5px;
  text-align: center;
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  .serial-number {
    background-color: #f1f1f1;
    min-width: 60px;
    display: inline-block;
    padding: 5px 0px;
    color: black;
  }
  .infinite-content {
    flex: 6;
    padding: 5px 0px;
    margin-left: 10px;
    text-align: left;
  }
  .infinite-content-key {
    color: black;
  }
  .infinite-content-key,
  .infinite-content-value {
    margin-left: 10px;
    flex: 3;
    text-align: left;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    padding: 5px 0px;
  }
}
.no-compare {
  width: 100%;
  height: 100%;
  text-align: center;
  line-height: 350px;
  color: #ccc;
  background-color: #f3f9fc;
  font-size: 25px;
}
.ip-error {
  color: red;
  margin: 5px 0;
  font-size: 13px;
}
.ip-empty {
  margin: 5px 0;
  height: 16.8px;
}
.el-loading-mask {
	background-color: rgba(255,255,255,.3);
}
</style>